//
// Copyright (c) 2005 BroadVision, Inc. All rights reserved.
//
// This software is copyrighted.  Under the copyright laws, this software
// may not be copied, in whole or in part, without prior written consent
// of BroadVision, Inc. or its assignees.  This software is provided under
// the terms of a license between BroadVision and the recipient, and its
// use is subject to the terms of that license.
//
// This software may be protected by one or more U.S. and International
// patents.  Certain applications of BroadVision One-To-One software are
// covered by U.S. patent 5,710,887.
//
// TRADEMARKS: BroadVision and BroadVision One-To-One are registered
// trademarks of BroadVision, Inc., in the United States and the European
// Community, and are trademarks of BroadVision, Inc., in other
// countries.  The BroadVision logo, is a trademark of BroadVision, Inc.,
// in the United States and other countries. Additionally, IONA and Orbix
// are trademarks of IONA Technologies, Ltd.  RSA, MD5, and RC2 are
// trademarks of RSA Data Security, Inc.
//

package com.broadvision.manage.common.tools.action.group;

import java.util.*;
import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.Globals;

import com.broadvision.data.client.DataManager;
import com.broadvision.web.util.ViewDynaBean;
import com.broadvision.system.accesscontrol.client.*;
import com.broadvision.visitor.client.Visitor;
import com.broadvision.visitor.client.VisitorContext;
import com.broadvision.visitor.client.VisitorGroupManager;
import com.broadvision.visitor.exceptions.VisitorGroupException;
import com.broadvision.visitor.interfaces.*;
import com.broadvision.visitor.utils.GroupContextParser;

import com.broadvision.manage.tools.action.BaseAction;
import com.broadvision.manage.common.tools.action.user.UserUtils;
import com.broadvision.portal.services.*;

/**
 * Browses a group.
 */
public class GroupPopupViewAction extends BaseAction {

  public static final String VIEW_BEAN_NAME = "mtGroupPopupView";
  public static final String DTO_BEAN_NAME  = "mtGroupPopupDTO";
  public static final String DELIM = "$#@!";

  /**
   * Implements the action for browsing a group.
   * <p> <p>
   * @param mapping <code>ActionMapping</code> object used to select this instance
   * @param form Optional <code>ActionForm</code> bean for this request (if any)
   * @param request <code>HttpServletRequest</code> object to process
   * @param response <code>HttpServletResponse</code> object to process
   * <p> <p>
   * @return <code>ActionForward</code> instance describing where and how
   * control should be forwarded, or null if the response has already been completed
   * <p> <p>
   * @throws Exception if an error occurs
   */
  public ActionForward processExecute(ActionMapping mapping,
                                      ActionForm form,
                                      HttpServletRequest request,
                                      HttpServletResponse response)
                               throws Exception
  {
    try {
      PortalVisitor agent = getPortalVisitor(request);
      Visitor visitor = agent.getVisitor();

      // Retrieve serviceName
      VisitorContext vc = agent.getContext();
      int serviceId = vc.getServiceId();
      String serviceName = DataManager.getServiceName(serviceId);

      String groupFQN = (String) UserUtils.getP(form, "groupFQN");
      ViewDynaBean view = new ViewDynaBean(VIEW_BEAN_NAME, mapping);
      request.setAttribute(VIEW_BEAN_NAME, view);
      UserUtils.setP(form, "executeSearch", Boolean.FALSE);
      UserUtils.setP(form, "groupName", "");
      // prepare for existing items
      boolean multiSelect = ((Boolean) UserUtils.getP(form, "multiSelect")).booleanValue();
      if (multiSelect) {
        String existingGroupFQNs = (String) UserUtils.getP(form, "existingGroupFQNs");
        if (!UserUtils.isEmptyString(existingGroupFQNs)) {
          List fqns = parseString(existingGroupFQNs, DELIM);
          String[] selectedIds = new String[fqns.size()];
          String[] selectedNames = new String[fqns.size()];
          Integer[] selectedReadOnlys = new Integer[fqns.size()];
          int i = 0;
          for (Iterator it = fqns.iterator(); it.hasNext();) {
            String fQN = (String) it.next();
            selectedIds[i] = fQN;
            selectedNames[i] = extractPathName(fQN);
            selectedReadOnlys[i] = new Integer(0);
            i++;
          }
          UserUtils.setP(form, "selectedItemIds", selectedIds);
          UserUtils.setP(form, "selectedItemNames", selectedNames);
          UserUtils.setP(form, "selectedItemReadOnlys", selectedReadOnlys);
        }
      }
      List dtos = new ArrayList();
      UserUtils.setP(view, "groupList", dtos);
      boolean userAdmin = isUserInRole(visitor, "UserAdmin");
      if (!userAdmin) { // non user admin
        AccessManager accessMgr = AccessManager.instance();
        List orgAdmins = accessMgr.getOwnerObjectsForPrincipal((Principal)visitor, "OrganizationAdmin");
        if ((null != orgAdmins) && (orgAdmins.size() > 0)) { // org admin
          if ("root".equals(groupFQN)) { // first time: use the top level nodes
            for (Iterator it = orgAdmins.iterator(); it.hasNext(); ) {
              ACObjectID ac = (ACObjectID) it.next();
              ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
              UserUtils.setP(oneDto, "fqn", ac.getObjectID());
              UserUtils.setP(oneDto, "name", extractPathName(ac.getObjectID()));
              dtos.add(oneDto);
            }
            UserUtils.setP(view, "numOfGroups", new Long(orgAdmins.size()));
            UserUtils.setP(view, "groupName", getResources(request, "mt.messages").getMessage(getLocale(request), "mt.group.label.root"));
          }
          else {
            return prepareForANode(groupFQN, view, dtos, orgAdmins, mapping, form, request);
          }
        }
        else {
          //request.setAttribute(Globals.ERROR_KEY, "error.group.noGroupAdmin");
          //return mapping.findForward("failure");
          // quietly return
        }
      }
      else { // user admin
        if ("root".equals(groupFQN)) {
          VisitorGroupManager vGroupMgr = null;
          List userGrpCxts = GroupContextParser.getUserGroupContextNames();
          if (null == userGrpCxts) {
            String defaultCxt = GroupContextParser.getDefaultNamingContextName();
            try {
              vGroupMgr = new VisitorGroupManager(defaultCxt);
              vGroupMgr.setServiceName(serviceName);
              if (!vGroupMgr.isRootContextValid()) {
                vGroupMgr.createRootContext();
              }
            }
            catch(Exception ex) {
              ex.printStackTrace();
              request.setAttribute(Globals.ERROR_KEY, "error.application");
              return mapping.findForward("failure");
            }
            VisitorGroup rootGroup = vGroupMgr.getRootVisitorGroup();
            if (!rootGroup.isActive()) {
              rootGroup.activate();
            }
            ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
            String gName = rootGroup.getName();
            int idx = gName.indexOf(":");
            if (idx > -1) {
              gName = gName.substring(idx + 1);
            }
            // UserUtils.setP(oneDto, "name", this.getLastGroupName(gName));
            UserUtils.setP(oneDto, "name", serviceName);
            String FQN = rootGroup.getFullyQualifiedName();
            String gpName = getPortalRootNameFromFQN(FQN);
            UserUtils.setP(view, "groupName", gpName);
            UserUtils.setP(oneDto, "fqn", rootGroup.getFullyQualifiedName());
            dtos.add(oneDto);
            UserUtils.setP(view, "numOfGroups", new Long(1));
          }
          else {
            for (Iterator it = userGrpCxts.iterator(); it.hasNext();) {
              String grpCName = (String) it.next();
              try {
                vGroupMgr = new VisitorGroupManager(grpCName);
                vGroupMgr.setServiceName(serviceName);
                if (!vGroupMgr.isRootContextValid()) {
                  vGroupMgr.createRootContext();
                }
              }
              catch(Exception ex) {
                ex.printStackTrace();
                continue;
                //request.setAttribute(Globals.ERROR_KEY, "error.application");
                //return mapping.findForward("failure");
              }
              VisitorGroup rootGroup = vGroupMgr.getRootVisitorGroup();
              if (!rootGroup.isActive()) {
                rootGroup.activate();
              }
              ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
              String gName = rootGroup.getName();
              int idx = gName.indexOf(":");
              if (idx > -1) {
                gName = gName.substring(idx + 1);
              }
              // UserUtils.setP(oneDto, "name", this.getLastGroupName(gName));
              UserUtils.setP(oneDto, "name", serviceName); 
              String FQN = rootGroup.getFullyQualifiedName();
              String gpName = getPortalRootNameFromFQN(FQN);
              UserUtils.setP(view, "groupName", gpName);   

              UserUtils.setP(oneDto, "fqn", rootGroup.getFullyQualifiedName());
              dtos.add(oneDto);
            }
            UserUtils.setP(view, "numOfGroups", new Long(userGrpCxts.size()));
          }
       //   UserUtils.setP(view, "groupName", getResources(request, "mt.messages").getMessage(getLocale(request), "mt.group.label.root"));
        }
        else {
          return prepareForANode(groupFQN, view, dtos, null, mapping, form, request);
        }
      }
    }
    catch (Exception ex) {
      request.setAttribute(Globals.ERROR_KEY, "error.application");
      return mapping.findForward("failure");
    }
    return mapping.findForward("success");
  }

  private ActionForward prepareForANode(String groupFQN,
					ViewDynaBean view,
					List dtos,
					List orgAdmins,
					ActionMapping mapping,
					ActionForm form,
					HttpServletRequest request)
    throws Exception
  {
    VisitorGroup thisGroup = VisitorGroupManager.getVisitorGroupByFqn(groupFQN);
    List subGroups = thisGroup.getSubGroups();
        //Added not null check on 11/11
    if(subGroups!=null && subGroups.size() >0 ){
    for (int i = 0; i < subGroups.size(); i++){
      VisitorGroup vG = (VisitorGroup) subGroups.get(i);
      ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
      UserUtils.setP(oneDto, "name", getLastGroupName(vG.getFriendlyName()));
      UserUtils.setP(oneDto, "fqn", vG.getFullyQualifiedName());
      dtos.add(oneDto);
    }
	}
    //UserUtils.setP(view, "groupName", thisGroup.getGroupName());
    UserUtils.setP(view, "groupName", getLastGroupName(thisGroup.getFriendlyName()));
    UserUtils.setP(view, "numOfGroups", new Long(subGroups.size()));
    // breadcrumb support
    HashMap orgAdminGroups = new HashMap();
    if (orgAdmins != null) {
      for (Iterator it = orgAdmins.iterator(); it.hasNext(); ) {
        ACObjectID ac = (ACObjectID)it.next();
        orgAdminGroups.put(ac.getObjectID(), ac);
      }
    }
    List parentGroupList = null;
	//Added try-catch block on 11/11
    try {
      parentGroupList = thisGroup.getParents(true);
	}catch(VisitorGroupException vgEx){
		//System.out.println("***** Not supported in ADS   ");
    }
    List theBreadcrumbs = new ArrayList();
    ViewDynaBean oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
 //   UserUtils.setP(oneDto, "name", getResources(request, "mt.messages").getMessage(getLocale(request), "mt.group.label.root"));
    UserUtils.setP(oneDto, "name",getPortalRootName(thisGroup.getFriendlyName())); 
    UserUtils.setP(oneDto, "fqn", "root");
    theBreadcrumbs.add(oneDto);
    boolean orgAdminCheck = ((Boolean)UserUtils.getP(form, "orgAdminCheck")).booleanValue();
    if (parentGroupList != null && parentGroupList.isEmpty() == false) {
      for (int i = parentGroupList.size() - 1; i >= 0; i--) {
        boolean skipParent = true && orgAdminCheck;
        VisitorGroup oneVisitorGroup = (VisitorGroup)parentGroupList.get(i);
        //Added not null check on 11/11
     	if(oneVisitorGroup!=null){
        String onefqn = oneVisitorGroup.getFullyQualifiedName();
        oneDto = new ViewDynaBean(DTO_BEAN_NAME, mapping);
        // change made to support groups by service
        String groupName = this.getLastGroupName(oneVisitorGroup.getFriendlyName());
        String scriptRoot= getPortalRootNameFromFQN(onefqn);
        if (!(groupName.equals(scriptRoot))){
          UserUtils.setP(oneDto, "name", groupName);
        }    
      //  UserUtils.setP(oneDto, "name", this.getLastGroupName(oneVisitorGroup.getFriendlyName()));
        theBreadcrumbs.add(oneDto);
        if (skipParent == true && orgAdmins != null && orgAdminGroups.containsKey(onefqn) == false) {
          continue;
        }
        else {
          skipParent = false;
        }
        UserUtils.setP(oneDto, "fqn", oneVisitorGroup.getFullyQualifiedName());
      }
    }
    }
    UserUtils.setP(view, "breadcrumbs", theBreadcrumbs);
    return mapping.findForward("success");
  }

  private String getLastGroupName(String name) {
    int i = name.lastIndexOf("/");
    if (i < 0) {
      return name;
    }
    else {
      return name.substring(i + 1);
    }
  }

  private String getPortalRootName(String name) {
     int i = name.lastIndexOf("/");
     if (i < 0) {
       return name;
     }
     else{
       StringTokenizer st = new StringTokenizer(name, "/");
       return st.nextToken();
     }
  }
  private String getPortalRootNameFromFQN(String name) {
     int i = name.lastIndexOf("/");
     if (i < 0) {
       return name;
     }
     else{
       StringTokenizer st = new StringTokenizer(name, "/");
       st.nextToken();
       return st.nextToken();
     }
  }
  private List parseString(String str, String separator) {
    List list = new ArrayList();
    int currPos = 0;
    while ((null != str) && (str.indexOf(separator, currPos) > 0)) {
      int nextPos = str.indexOf(separator, currPos);
      list.add(str.substring(currPos, nextPos));
      currPos = nextPos + separator.length();
    }
    if (currPos < str.length()) {
      list.add(str.substring(currPos));
    }
    return list;
  }

  private String extractPathName(String fqn) {
    int i = fqn.indexOf(":");
    if (i < 0) {
      return fqn;
    }
    else {
      return fqn.substring(i + 1);
    }
  }
}
